package com.zg.job.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zg.common.core.A;
import com.zg.common.core.C;
import com.zg.common.core.R;
import com.zg.common.core.dao.system.SysJob;
import com.zg.common.core.dao.system.SysJobDao;
import com.zg.job.enm.JobStateEnum;
import com.zg.job.service.BatchService;
import com.zg.job.service.QuartzService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * @author Zxb
 */
@Slf4j
@RestController
@AllArgsConstructor
public class JobController {

    private QuartzService quartzService;
    private SysJobDao jobDao;

    private BatchService batchService;

    @GetMapping("/job/page")
    public R<?> page(String searchStr, Integer page, Integer pageSize) {
        IPage<SysJob> pageParam = new Page<>(page, pageSize);
        QueryWrapper<SysJob> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(searchStr)) {
            queryWrapper.lambda().like(SysJob::getName, "%" + searchStr + "%");
        }
        IPage<SysJob> result = jobDao.page(pageParam, queryWrapper);
        return R.success(result);
    }

    @PostMapping("/job/changeCorn")
    public R<?> change(@RequestBody Map<String, String> map) {
        Long id = Long.valueOf(map.get("id"));
        String cron = map.get("cron");
        SysJob job = jobDao.getById(id);
        String oldCron = job.getCron();
        try {
            quartzService.modifyJob(job, cron);
            job.setCron(cron);
            jobDao.updateById(job);
        } catch (SchedulerException e) {
            log.error(e.getMessage(),e);
            job.setCron(oldCron);
            jobDao.updateById(job);
            return R.error();
        }
        return R.success();
    }

    @PostMapping("/job/pause")
    public R<?> pause(@RequestBody Long id) {
        SysJob job = jobDao.getById(id);
        try {
            quartzService.pauseJob(job);
            job.setState(JobStateEnum.暂停.name());
            jobDao.updateById(job);
        } catch (SchedulerException e) {
            log.error(e.getMessage(),e);
            return R.error();
        }
        return R.success();
    }

    @PostMapping("/job/resume")
    public R<?> resume(@RequestBody Long id) {
        SysJob job = jobDao.getById(id);
        try {
            quartzService.resumeJob(job);
            job.setState(JobStateEnum.运行.name());
            jobDao.updateById(job);
        } catch (SchedulerException e) {
            log.error(e.getMessage(),e);
            return R.error();
        }
        return R.success();
    }

    @PostMapping("/job/del")
    public R<?> del(@RequestBody List<Long> ids) {
        for (Long id : ids) {
            SysJob job = jobDao.getById(id);
            try {
                quartzService.delJob(job);
                jobDao.removeById(id);
            } catch (SchedulerException e) {
                log.error(e.getMessage(),e);
            }
        }
        return R.success();
    }

    @PostMapping("/job/stop")
    public R<?> stop(@RequestBody Long id) {
        SysJob job = jobDao.getById(id);
        try {
            quartzService.delJob(job);
            job.setState(JobStateEnum.下线.name());
            jobDao.updateById(job);
        } catch (SchedulerException e) {
            log.error(e.getMessage(),e);
            return R.error();
        }
        return R.success();
    }

    @PostMapping("/job/add")
    public R<?> add(@RequestBody SysJob job) {
        if (jobDao.exists(new QueryWrapper<SysJob>()
                .lambda().eq(SysJob::getName, job.getName()))) {
            return R.error("任务名称已经存在");
        }
        job.setState(JobStateEnum.下线.name());
        jobDao.save(job);
        return R.success();
    }

    @PostMapping("/job/update")
    public R update(@RequestBody @Valid SysJob obj) {
        SysJob old = jobDao.getById(obj.getId());
        A.isInDatabase(old, "定时任务");
        if (jobDao.exists(
                new QueryWrapper<SysJob>()
                        .lambda()
                        .eq(SysJob::getName, obj.getName())
                        .ne(SysJob::getId, old.getId())
        )) {
            return R.error("任务名称已经存在");
        }

        if (jobDao.exists(
                new QueryWrapper<SysJob>()
                        .lambda()
                        .eq(SysJob::getCode, obj.getCode())
                        .ne(SysJob::getId, old.getId())
        )) {
            return R.error("任务编码已经存在");
        }
        BeanUtil.copyProperties(obj, old, C.IGNORED_PROPERTIES);
        jobDao.updateById(old);
        return R.success();
    }

    @PostMapping("/job/start")
    public R<?> start(@RequestBody Long id) {
        SysJob job = jobDao.getById(id);
        try {
            quartzService.addJob(job);
            job.setState(JobStateEnum.运行.name());
            jobDao.updateById(job);
        } catch (SchedulerException e) {
            log.error(e.getMessage(),e);
            job.setState(JobStateEnum.下线.name());
            jobDao.updateById(job);
            return R.error();
        }
        return R.success();
    }

    @PostMapping("/job/do")
    public R<?> go(@RequestBody Long id) {
        //SysJob job = jobDao.getById(id);
        try {
            batchService.doJob(id);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            return R.error();
        }
        return R.success();
    }

    @GetMapping("/job/demo")
    public R<?> demo() {
        return R.success("测试任务");
    }
}
